/* Copyright (c) 2025 Beijing Semidrive Technology Corporation
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @file  SpiSlave_Slave.c
 * @brief Semidrive. AUTOSAR 4.3.1 MCAL SpiSlave plugins.
 */
#ifdef __cplusplus
extern "C" {
#endif

/*******************************************************************************
**                      Include Section                                       **
*******************************************************************************/
#include "cdefs.h"
#include "Std_Types.h"
#include "SpiSlave.h"
#include "SpiSlave_Cfg.h"
#include "SchM_SpiSlave.h"
#include "SpiSlave_PbCfg.h"
#include "SpiSlave_Ip.h"
#include "SpiSlave_Mld.h"
#include "SpiSlave_Types.h"
#include "SpiSlave_Driver.h"

#if (SPI_SLV_DEV_ERROR_DETECT == STD_ON)
#include "Det.h"
#endif
#if (SPI_SLV_E_HARDWARE_ERROR == STD_ON)
#include <Dem.h> /* DEM declarations */
#endif /* #if (SPI_SLV_E_HARDWARE_ERROR == STD_ON) */

/*******************************************************************************
**                      Function Definitions                                  **
*******************************************************************************/

#define SPI_SLV_START_SEC_CODE_FAST
#include "SpiSlave_MemMap.h"

/** @brief SpiSlave_ChannelDetCheck
 **
 ** To perform basic DET checks related to channels
 **
 ** @param [in] Channel   - Channel ID.
 ** @param [in] SId  - Service ID for Error Reporting
 ** @param [out] None
 ** @return  E_OK: No err related to channels be detected.
 **          E_NOT_OK: The err related to channels be detected.
 */
#if (SPI_SLV_DEV_ERROR_DETECT == STD_ON)
FUNC(Std_ReturnType, SPI_SLV_CODE)
SpiSlave_ChannelDetCheck(const SpiSlave_ChannelType Channel, const uint8 SId)
{
    uint8 CoreId = SpiSlave_GetCoreID();
    struct SpiSlave_Driver_Handler *PerCoreHandler = SpiSlaveHandler[CoreId];
#if (SPI_SLV_CHANNEL_BUFFERS_ALLOWED == 0x2)
    /* Local Pointer for Channel configuration structure */
    P2CONST(SpiSlave_ChannelCfgType, AUTOMATIC, SPI_SLV_CONFIG_CONST)
    tmpChannelConfig;
#endif
    Std_ReturnType ReturnValue;
    ReturnValue = E_OK;

    /* Check if SPI Driver is initialized */
    if (SPI_SLV_UNINIT == PerCoreHandler->SpiSlave_HandlerStatus) {
        /* Report to DET */
        (void)Det_ReportError(SPI_SLV_MODULE_ID, SPI_SLV_INSTANCE_ID, SId, SPI_SLV_E_UNINIT);
        ReturnValue = E_NOT_OK;
    } else {
        /* No action required */
    }

    /* Check if the channel ID passed, is valid */
    if (SPI_SLV_MAX_CHANNEL <= (uint16)Channel) {

        /* Report to DET */
        (void)Det_ReportError(SPI_SLV_MODULE_ID, SPI_SLV_INSTANCE_ID, SId, SPI_SLV_E_PARAM_CHANNEL);
        ReturnValue = E_NOT_OK;
    }
    else
    {
        /* Check assign to cur core ?  */
        if (SpiSlave_GetChannelAssignCoreId(Channel) != CoreId) {

            /* Report to DET */
            (void)Det_ReportError(SPI_SLV_MODULE_ID, SPI_SLV_INSTANCE_ID, SId, SPI_SLV_E_ILLEGAL_RES);
            ReturnValue = E_NOT_OK;
        } else {
            /* No action required */
        }
    }
    /*check if the channel buffer allowed is IB/EB */
#if (SPI_SLV_CHANNEL_BUFFERS_ALLOWED == 0x2)

    if (E_OK == ReturnValue) {
        /* Get the Channel configuration structure of the requested channel */
        tmpChannelConfig = &SpiSlave_ChannelConfig[Channel];

        if ((SPI_SLV_READIB_SID == SId) || (SPI_SLV_WRITEIB_SID == SId)) {
            /* Check if the channel is configured with external buffer */
            if (tmpChannelConfig->ChannelBufferType == SPI_SLV_EB) {
                /* Report to DET */
                (void)Det_ReportError(SPI_SLV_MODULE_ID, SPI_SLV_INSTANCE_ID, SId, SPI_SLV_E_CHANNEL_OPS);
                ReturnValue = E_NOT_OK;
            } else {
                /* No action required */
            }
        } else {
            /* Check if the requested channel is configured for internal buffer */
            if (tmpChannelConfig->ChannelBufferType == SPI_SLV_IB) {
                /* Report to DET */
                (void)Det_ReportError(SPI_SLV_MODULE_ID, SPI_SLV_INSTANCE_ID, SId, SPI_SLV_E_CHANNEL_OPS);
                ReturnValue = E_NOT_OK;
            } else {
                /* No action required */
            }
        }
    } else {
        /* Do Nothing */
    }

#endif

    return ReturnValue;
}
#endif

/** @brief SpiSlave_SeqIdDetCheck
 **
 ** To perform basic Det Checks for sequence Transmission request
 **
 ** @param [out] Sequence  - Sequence ID.
 ** @param [in]  SID  - Service ID for Error Reporting
 ** @param [out] None
 ** @return  E_OK: No err related to Seq be detected.
 **          E_NOT_OK: The err related to Seq be detected.
 */
#if (SPI_SLV_DEV_ERROR_DETECT == STD_ON)
FUNC(Std_ReturnType, SPI_SLV_CODE)
SpiSlave_SeqIdDetCheck(const SpiSlave_SequenceType Sequence, const uint8 SId)
{
    /* To return DET Error Status */
    Std_ReturnType ReturnValue;
    /* Initialise thereturn value with E_OK */
    ReturnValue = E_OK;
    uint8 CoreId = SpiSlave_GetCoreID();
    struct SpiSlave_Driver_Handler *PerCoreHandler = SpiSlaveHandler[CoreId];

    /* Check if SPI Driver is initialized */
    if (SPI_SLV_UNINIT == PerCoreHandler->SpiSlave_HandlerStatus) {
        /* Report to DET */
        (void)Det_ReportError(SPI_SLV_MODULE_ID, SPI_SLV_INSTANCE_ID, SId, SPI_SLV_E_UNINIT);
        ReturnValue = E_NOT_OK;
    } else {
        /* No action required */
    }

    /* Check if the sequence ID passed, is valid */

    if (SPI_SLV_MAX_SEQUENCE <= Sequence) {
        /* Report to DET */
        (void)Det_ReportError(SPI_SLV_MODULE_ID, SPI_SLV_INSTANCE_ID, SId, SPI_SLV_E_PARAM_SEQ);
        ReturnValue = E_NOT_OK;
    }
    else
    {
      /* Check if  assign to cur core?  */
      if (SpiSlave_GetSequenceAssignCoreId(Sequence) != CoreId) {

          /* Report to DET */
          (void)Det_ReportError(SPI_SLV_MODULE_ID, SPI_SLV_INSTANCE_ID, SId, SPI_SLV_E_ILLEGAL_RES);
          ReturnValue = E_NOT_OK;
      } else {
          /* No action required */
      }
    }

    return ReturnValue;
}
#endif

#if (SPI_SLV_DEV_ERROR_DETECT == STD_ON)
static FUNC(Std_ReturnType, SPI_SLV_CODE)
SpiSlave_ChannelDetBuffCheck(const SpiSlave_ChannelType Channel, const uint8 SId,
                        const SpiSlave_DataBufferType *BuffPtr)
{
    uint8 align_size;
    /* Local Pointer for Channel configuration structure */
    P2CONST(SpiSlave_ChannelCfgType, AUTOMATIC, SPI_SLV_CONFIG_CONST)
    tmpChannelConfig;

    Std_ReturnType ReturnValue;
    ReturnValue = E_OK;

    /* Get the Channel configuration structure of the requested channel */
    tmpChannelConfig = &SpiSlave_ChannelConfig[Channel];

    if (tmpChannelConfig->DataWidth < 0x9U) {
        align_size = 1;
    } else if (tmpChannelConfig->DataWidth < 0x11U) {
        align_size = 2;
    } else {
        align_size = 4;
    }
    /* Check if the channel is configured with external buffer */

    if(SPI_SLV_READIB_SID == SId && NULL_PTR == BuffPtr ){
        /* Report to DET */
        (void)Det_ReportError(SPI_SLV_MODULE_ID, SPI_SLV_INSTANCE_ID, SId, SPI_SLV_E_PARAM_POINTER);
        ReturnValue = E_NOT_OK;
    }
    if (!SPISLV_IS_ALIGNED(BuffPtr, align_size)) {
        /* Report to DET */
        (void)Det_ReportError(SPI_SLV_MODULE_ID, SPI_SLV_INSTANCE_ID, SId, SPI_SLV_E_CHANNEL_ALIGN);
        ReturnValue = E_NOT_OK;
    }

    return ReturnValue;
}
#endif
#if (SPI_SLV_DEV_ERROR_DETECT == STD_ON)
static FUNC(Std_ReturnType, SPI_SLV_CODE)
SpiSlave_JobIdDetCheck(const SpiSlave_JobType JobId, const uint8 SId)
{
    /* To return DET Error Status */
    Std_ReturnType ReturnValue;
    /* Initialise thereturn value with E_OK */
    ReturnValue = E_OK;
    uint8 CoreId = SpiSlave_GetCoreID();
    struct SpiSlave_Driver_Handler *PerCoreHandler = SpiSlaveHandler[CoreId];

    /* Check if SPI Driver is initialized */
    if (SPI_SLV_UNINIT == PerCoreHandler->SpiSlave_HandlerStatus) {
        /* Report to DET */
        (void)Det_ReportError(SPI_SLV_MODULE_ID, SPI_SLV_INSTANCE_ID, SId, SPI_SLV_E_UNINIT);
        ReturnValue = E_NOT_OK;
    } else {
        /* No action required */
    }

    /* Check if the sequence ID passed, is valid */

    if (SPI_SLV_MAX_JOB <= JobId) {
        /* Report to DET */
        (void)Det_ReportError(SPI_SLV_MODULE_ID, SPI_SLV_INSTANCE_ID, SId, SPI_SLV_E_PARAM_JOB);
        ReturnValue = E_NOT_OK;
    }
    else
    {
        /* Check if  assign to cur core?  */
        if (SpiSlave_GetJobAssignCoreId(JobId) != CoreId) {

            /* Report to DET */
            (void)Det_ReportError(SPI_SLV_MODULE_ID, SPI_SLV_INSTANCE_ID, SId, SPI_SLV_E_ILLEGAL_RES);
            ReturnValue = E_NOT_OK;
        } else {
            /* No action required */
        }
    }

    return ReturnValue;
}
#endif

#define SPI_SLV_STOP_SEC_CODE_FAST
#include "SpiSlave_MemMap.h"

#define SPI_SLV_START_SEC_CODE
#include "SpiSlave_MemMap.h"
/** @brief SpiSlave_Init
**
** Initializes the SPI hardware units and driver.
**
** @param [in] None
** @param [out] None
** @return None
*/

FUNC(void, SPI_SLV_CODE)
SpiSlave_Init(P2CONST(SpiSlave_ConfigType, AUTOMATIC, SPI_SLV_APPL_CONST) ConfigPtr)
{
    uint8 CoreId = SpiSlave_GetCoreID();
    struct SpiSlave_Driver_Handler *PerCoreHandler = SpiSlaveHandler[CoreId];
    Std_ReturnType ReturnValue = E_OK;
#if (SPI_SLV_DEV_ERROR_DETECT == STD_ON)

    /* check for DET Errors */
    if (NULL_PTR == ConfigPtr) {
        /* Report to DET */
        (void)Det_ReportError(SPI_SLV_MODULE_ID, SPI_SLV_INSTANCE_ID, SPI_SLV_INIT_SID, SPI_SLV_E_PARAM_POINTER);
        ReturnValue = E_NOT_OK;
    } else if (SPI_SLV_UNINIT != PerCoreHandler->SpiSlave_HandlerStatus) {

        /* Report to DET */
        (void)Det_ReportError(SPI_SLV_MODULE_ID, SPI_SLV_INSTANCE_ID, SPI_SLV_INIT_SID, SPI_SLV_E_ALREADY_INITIALIZED);
        ReturnValue = E_NOT_OK;
    } else {
        /* Do Nothing */
    }

    /* If no DET errors, continue */
#endif /* (SPI_SLV_DEV_ERROR_DETECT == STD_ON) */

    /* Initialize the module only if Database is present or no DET is reported */
    if (E_OK == ReturnValue) {
        /* Initialise the global variables */
        SpiSlave_InitData();
        /* Initialise the Hardware */
        ReturnValue = SpiSlave_HWInit();

        if (ReturnValue == E_OK) {
            /* Global Status variable is SPI_SLV_IDLE */
            PerCoreHandler->SpiSlave_HandlerStatus = SPI_SLV_IDLE;
            PerCoreHandler->SpiSlave_HandlerAsyncStatus = SPI_SLV_IDLE;
        } else {
            /* Update the SPI driver status as uninitialized */
            PerCoreHandler->SpiSlave_HandlerStatus = SPI_SLV_UNINIT;
            PerCoreHandler->SpiSlave_HandlerAsyncStatus = SPI_SLV_UNINIT;
        }
    }
}

/** @brief SpiSlave_DeInit
**
** Deinitialize the SPI hardware units and driver.
**
** @param [in] None
** @param [out] None
** @return None
*/
FUNC(Std_ReturnType, SPI_SLV_CODE)
SpiSlave_DeInit(void)
{
    Std_ReturnType ReturnValue;
    ReturnValue = E_NOT_OK;
    uint8 CoreId = SpiSlave_GetCoreID();
    struct SpiSlave_Driver_Handler *PerCoreHandler = SpiSlaveHandler[CoreId];
#if (SPI_SLV_DEV_ERROR_DETECT == STD_ON)

    /* Check if SPI Driver is initialized */
    if (SPI_SLV_UNINIT == PerCoreHandler->SpiSlave_HandlerStatus) {
        /* Report to DET */
        (void)Det_ReportError(SPI_SLV_MODULE_ID, SPI_SLV_INSTANCE_ID, SPI_SLV_DEINIT_SID, SPI_SLV_E_UNINIT);
    } else
#endif
    {
        SchM_Enter_SpiSlave_SPI_SLV_EXCLUSIVE_AREA_01();

        /* Check if Global status variable is SPI_SLV_BUSY */
        if (SPI_SLV_BUSY != SpiSlave_GetStatus()) {

            ReturnValue = SpiSlave_HWDeInit();
            /* Update the SPI driver status as uninitialized */
            PerCoreHandler->SpiSlave_HandlerStatus = SPI_SLV_UNINIT;
            PerCoreHandler->SpiSlave_HandlerAsyncStatus = SPI_SLV_UNINIT;
        } else {
            /* No action required */
        }

        SchM_Exit_SpiSlave_SPI_SLV_EXCLUSIVE_AREA_01();
    }

    return (ReturnValue);
}
#define SPI_SLV_STOP_SEC_CODE
#include "SpiSlave_MemMap.h"

#define SPI_SLV_START_SEC_CODE_FAST
#include "SpiSlave_MemMap.h"
/** @brief SpiSlave_WriteIB
**
** Writing one or more data to an IB SPI Handler/Driver channel.
**
** @param [in] Channel  Channel Id.
** @param [in] DataBufferPtr  Buffer to write the data.
** @return E_OK: write command has been accepted.
**         E_NOT_OK: write command has not been accepted.
*/
#if ((SPI_SLV_CHANNEL_BUFFERS_ALLOWED == 0x0) || (SPI_SLV_CHANNEL_BUFFERS_ALLOWED == 0x2))

FUNC(Std_ReturnType, SPI_SLV_CODE)
SpiSlave_WriteIB(SpiSlave_ChannelType Channel, const SpiSlave_DataBufferType *DataBufferPtr)
{
    void *tmpBufferIndex;
    uint8 CoreId = SpiSlave_GetCoreID();
    Std_ReturnType ReturnValue = E_OK;
    struct SpiSlave_Driver_Handler *PerCoreHandler = SpiSlaveHandler[CoreId];
    P2CONST(SpiSlave_ChannelCfgType, AUTOMATIC,
            SPI_SLV_APPL_CONST)
    tmpPtrChannelConfig = &SpiSlave_ChannelConfig[Channel];

#if (SPI_SLV_DEV_ERROR_DETECT == STD_ON)
    /* Check for DET Errors */
    ReturnValue = SpiSlave_ChannelDetCheck(Channel, SPI_SLV_WRITEIB_SID);
    /* Check aligin  DET Errors */
    ReturnValue |= SpiSlave_ChannelDetBuffCheck(Channel, SPI_SLV_WRITEIB_SID,
                                           (const SpiSlave_DataBufferType *)DataBufferPtr);
#endif /* End of (SPI_SLV_DEV_ERROR_DETECT == STD_ON) */
    /* Check if any DET error has occurred */
    SchM_Enter_SpiSlave_SPI_SLV_EXCLUSIVE_AREA_02();

    if (E_OK == ReturnValue) {
        if (PerCoreHandler->SpiSlave_SpiChannelState[Channel].BuffLock == B_SLV_LOCKED) {
            ReturnValue = E_NOT_OK;
        }
    }

    if (E_OK == ReturnValue) {
        tmpBufferIndex = (void *)tmpPtrChannelConfig->WriteBufferIndex;
        PerCoreHandler->SpiSlave_SpiChannelState[Channel].BuffLock = B_SLV_LOCKED;
        SchM_Exit_SpiSlave_SPI_SLV_EXCLUSIVE_AREA_02();

        if (DataBufferPtr != NULL_PTR) {
            for (uint16 i = 0; i < tmpPtrChannelConfig->BufferSize; i++) {
                /* Copy the data to internal buffer*/
                /* Handling of data width by typecast as per SWS_SpiSlave_00437 requirement*/
                if (tmpPtrChannelConfig->DataWidth < 0x9U) {
                    *(((uint8 *)tmpBufferIndex + i)) = *(((const uint8 *)DataBufferPtr) + i);
                } else if (tmpPtrChannelConfig->DataWidth < 0x11U) {
                    /*PRQA S 3305 4*/
                    *(((uint16 *)tmpBufferIndex + i)) = *(((const uint16 *)DataBufferPtr) + i);
                } else {
                    *(((uint32 *)tmpBufferIndex + i)) = *(((const uint32 *)DataBufferPtr) + i);
                }
            }
        } else {
            /* Write the Default Data */
            for (uint16 i = 0; i < tmpPtrChannelConfig->BufferSize; i++) {
                if (tmpPtrChannelConfig->DataWidth < 0x9U) {
                    *(((uint8 *)tmpBufferIndex + i)) = (uint8)(tmpPtrChannelConfig->DefaultValue);
                } else if (tmpPtrChannelConfig->DataWidth < 0x11U) {
                    *(((uint16 *)tmpBufferIndex + i)) = (uint16)(tmpPtrChannelConfig->DefaultValue);
                } else {
                    *(((uint32 *)tmpBufferIndex + i)) = tmpPtrChannelConfig->DefaultValue;
                }
            }
        }

        PerCoreHandler->SpiSlave_SpiChannelState[Channel].BuffLock = B_SLV_UNLOCK;
        PerCoreHandler->SpiSlave_SpiChannelState[Channel].BuffSta = B_SLV_SETED;
    } else {
        SchM_Exit_SpiSlave_SPI_SLV_EXCLUSIVE_AREA_02();
    }

    return (ReturnValue);
}

#endif

/** @brief SpiSlave_AsyncTransmit
**
** Transmitting data asynchronously.
**
** @param [in] Sequence  Sequence to be transmitted
** @param [out] None
** @return E_OK: Transmission command has been accepted
**         E_NOT_OK: Transmission command has not been accepted
*/
#if ((SPI_SLV_LEVEL_DELIVERED == SPI_SLV_LEVEL_1) || (SPI_SLV_LEVEL_DELIVERED == SPI_SLV_LEVEL_2))

FUNC(Std_ReturnType, SPI_SLV_CODE)
SpiSlave_AsyncTransmit(SpiSlave_SequenceType Sequence)
{
    Std_ReturnType ReturnValue;
#if (SPI_SLV_DEV_ERROR_DETECT == STD_ON)

    ReturnValue = SpiSlave_SeqIdDetCheck(Sequence, SPI_SLV_ASYNCTRANSMIT_SID);

    if (E_OK == ReturnValue)
#endif /* SPI_SLV_DEV_ERROR_DETECT == STD_ON */
    {
        ReturnValue = SpiSlave_HwAsyncTransmit(Sequence);
    }

    return ReturnValue;
}

#endif

/** @brief SpiSlave_ReadIB
**
** reading one or more data from an IB SPI Handler/Driver channel
**
** @param [in] Channel  Channel id
** @param [out] DataBufferPointer  To read the buffer data
** @return E_OK: Read command has been accepted
**         E_NOT_OK: Read command has not been accepted
*/
#if ((SPI_SLV_CHANNEL_BUFFERS_ALLOWED == 0x0) || \
     (SPI_SLV_CHANNEL_BUFFERS_ALLOWED == 0x2))

FUNC(Std_ReturnType, SPI_SLV_CODE)
SpiSlave_ReadIB(SpiSlave_ChannelType Channel, SpiSlave_DataBufferType *DataBufferPointer)
{
    Std_ReturnType ReturnValue = E_OK;
    P2CONST(SpiSlave_ChannelCfgType, AUTOMATIC, SPI_SLV_APPL_CONST)
    tmpPtrChannelConfig = &SpiSlave_ChannelConfig[Channel];

#if (SPI_SLV_DEV_ERROR_DETECT == STD_ON)
    /* Check for DET Errors */
    ReturnValue = SpiSlave_ChannelDetCheck(Channel, SPI_SLV_READIB_SID);
    /* Check aligin  DET Errors */
    ReturnValue |= SpiSlave_ChannelDetBuffCheck(Channel, SPI_SLV_READIB_SID,
                                            (const SpiSlave_DataBufferType *)DataBufferPointer);
#endif /* End of (SPI_SLV_DEV_ERROR_DETECT == STD_ON) */

    /* Check if any DET error has occurred */
    if (ReturnValue == E_OK) {
        /*PRQA S 2991,2995 2*/
        for (uint16 i = 0; i < tmpPtrChannelConfig->BufferSize; i++) {
            /* Copy the data to internal buffer*/
            /* Handling of data width by typecast as per SWS_SpiSlave_00437 requirement*/
            if (tmpPtrChannelConfig->DataWidth < 0x9U) {
                *(((uint8 *)DataBufferPointer) + i) = *(((uint8 *)tmpPtrChannelConfig->ReadBufferIndex + i));
            } else if (tmpPtrChannelConfig->DataWidth < 0x11U) {
                /*PRQA S 3305 4*/
                *(((uint16 *)DataBufferPointer) + i) = *(((uint16 *)tmpPtrChannelConfig->ReadBufferIndex + i));
            } else {
                *(((uint32 *)DataBufferPointer) + i) = *(((uint32 *)tmpPtrChannelConfig->ReadBufferIndex + i));
            }
        }
    } /* End of all operations if there is no DET error */

    return (ReturnValue);
}

#endif

/** @brief SpiSlave_SetupEB
**
** setting the buffers and the length of data for the external buffer
**
** @param [in] Channel  Channel id
** @param [in] Length   Data length
** @param [out] SrcDataBufferPtr  To read the buffer data
** @param [out] DesDataBufferPtr  To read the buffer data
** @return E_OK: Setup command has been accepted
**         E_NOT_OK: Setup command has not been accepted
*/
#if ((SPI_SLV_CHANNEL_BUFFERS_ALLOWED == 0x1) || \
     (SPI_SLV_CHANNEL_BUFFERS_ALLOWED == 0x2))

FUNC(Std_ReturnType, SPI_SLV_CODE)
SpiSlave_SetupEB(SpiSlave_ChannelType Channel,
            const SpiSlave_DataBufferType *SrcDataBufferPtr,
            SpiSlave_DataBufferType *DesDataBufferPtr,
            SpiSlave_NumberOfDataType Length)
{
    void *tmpBufferIndex;
    uint8 CoreId = SpiSlave_GetCoreID();
    Std_ReturnType ReturnValue = E_OK;
    P2CONST(SpiSlave_ChannelCfgType, AUTOMATIC, SPI_SLV_APPL_CONST) tmpPtrChannelConfig;
    P2VAR(SpiSlave_EBDataType, AUTOMATIC, SPI_SLV_APPL_DATA) tmpPtrEBData;
    struct SpiSlave_Driver_Handler *PerCoreHandler = SpiSlaveHandler[CoreId];
#if (SPI_SLV_DEV_ERROR_DETECT == STD_ON)
    /* Check for DET Errors */
    ReturnValue = SpiSlave_ChannelDetCheck(Channel, SPI_SLV_SETUPEB_SID);

    /* Check if any DET error has occurred */
    if (E_OK == ReturnValue) {
        tmpPtrChannelConfig = &SpiSlave_ChannelConfig[Channel];

        /*
         * Check if the 'length' parameter is greater than configured length and if
         * length is equal to zero
         */
        if ((Length == 0x0U) || (Length > (tmpPtrChannelConfig->BufferSize))) {
            /* Report to DET */
            (void)Det_ReportError(SPI_SLV_MODULE_ID, SPI_SLV_INSTANCE_ID, SPI_SLV_SETUPEB_SID, SPI_SLV_E_PARAM_LENGTH);
            ReturnValue = E_NOT_OK;
        } else {
            /* No action required */
        }
    } else {
        /* No action required */
    }

    /*
        Note:
        For performance, when the data width is greater than 8 and less than 17bits, the external
      memory area is required to be aligned to the double-byte boundary. Similarly, the 17-32bits
      byte needs to be aligned to the 4-byte boundary.
    */
    /* Check aligin  DET Errors */
    ReturnValue |= SpiSlave_ChannelDetBuffCheck(Channel, SPI_SLV_SETUPEB_SID,
                                           (const SpiSlave_DataBufferType *)SrcDataBufferPtr);
    /* Check aligin  DET Errors */
    ReturnValue |= SpiSlave_ChannelDetBuffCheck(Channel, SPI_SLV_SETUPEB_SID,
                                           (const SpiSlave_DataBufferType *)DesDataBufferPtr);

    /* Check aligin  DET Errors */
    if (SrcDataBufferPtr == NULL_PTR && DesDataBufferPtr == NULL_PTR) {
        ReturnValue = E_NOT_OK;
    }

#endif /* End of (SPI_SLV_DEV_ERROR_DETECT == STD_ON) */
    /* Check if any DET error has occurred */
    SchM_Enter_SpiSlave_SPI_SLV_EXCLUSIVE_AREA_05();

    if (E_OK == ReturnValue) {
        if (PerCoreHandler->SpiSlave_SpiChannelState[Channel].BuffLock == B_SLV_LOCKED){
            ReturnValue = E_NOT_OK;
        }
    }

    if (E_OK == ReturnValue) {
        /*
            Put this code in this position, in order to avoid calling SetupEB before initialization,
            which will cause data access exception.
        */
        tmpPtrChannelConfig = &SpiSlave_ChannelConfig[Channel];
        tmpBufferIndex = (void *)tmpPtrChannelConfig->WriteBufferIndex;
        PerCoreHandler->SpiSlave_SpiChannelState[Channel].BuffLock = B_SLV_UNLOCK;
        SchM_Exit_SpiSlave_SPI_SLV_EXCLUSIVE_AREA_05();

        if (SrcDataBufferPtr == NULL_PTR) {
            for (uint16 i = 0; i < tmpPtrChannelConfig->BufferSize; i++) {
                if (tmpPtrChannelConfig->DataWidth < 0x9U) {
                    *(((uint8 *)tmpBufferIndex + i)) = (uint8)(tmpPtrChannelConfig->DefaultValue);
                } else if (tmpPtrChannelConfig->DataWidth < 0x11U) {
                    *(((uint16 *)tmpBufferIndex + i)) = (uint16)(tmpPtrChannelConfig->DefaultValue);
                } else {
                    *(((uint32 *)tmpBufferIndex + i)) = tmpPtrChannelConfig->DefaultValue;
                }
            }
        }

        /* Get the EB pointer of the requested channel */
        tmpPtrEBData = &PerCoreHandler->ExtBuff[Channel];
        /*Copy the source pointer to global variable    */
        tmpPtrEBData->SrcDataBufferPtr = (SrcDataBufferPtr == NULL_PTR ?
                                          tmpPtrChannelConfig->WriteBufferIndex : SrcDataBufferPtr);
        /* Copy the destination pointer to global variable */
        tmpPtrEBData->DesDataBufferPtr = DesDataBufferPtr;
        /* Copy length for that channel */
        tmpPtrEBData->Length = Length;
        /* SWS_SpiSlave_00037 for each Channel with EB declared before call a Transmit method */
        PerCoreHandler->SpiSlave_SpiChannelState[Channel].BuffLock = B_SLV_UNLOCK;
        PerCoreHandler->SpiSlave_SpiChannelState[Channel].BuffSta = B_SLV_SETED;
        SPI_SLV_DBG("Ch %d TX Buff valid\n", Channel);
    } else {
        SchM_Exit_SpiSlave_SPI_SLV_EXCLUSIVE_AREA_05();
    }

    return (ReturnValue);
}
#endif
#define SPI_SLV_STOP_SEC_CODE_FAST
#include "SpiSlave_MemMap.h"

#define SPI_SLV_START_SEC_CODE
#include "SpiSlave_MemMap.h"
/** @brief SpiSlave_GetStatus
**
** getting the status of SPI Driver Component
**
** @param [in] None
** @param [out] None
** @return SpiSlave_HandlerStatus:SpiSlave_Slave status type
*/
FUNC(SpiSlave_StatusType, SPI_SLV_CODE)
SpiSlave_GetStatus(void)
{
    SpiSlave_StatusType ret;
    uint8 CoreId = SpiSlave_GetCoreID();
    struct SpiSlave_Driver_Handler *PerCoreHandler = SpiSlaveHandler[CoreId];

    if (SPI_SLV_UNINIT == PerCoreHandler->SpiSlave_HandlerStatus) {
        ret = SPI_SLV_UNINIT;
    } else if (PerCoreHandler->SpiSlave_HandlerStatus == SPI_SLV_BUSY ||
               PerCoreHandler->SpiSlave_HandlerAsyncStatus == SPI_SLV_BUSY) {
        ret = SPI_SLV_BUSY;
    } else {
        ret = SPI_SLV_IDLE;
    }

    return ret;
}

/** @brief SpiSlave_GetJobResult
 **
 ** getting result of the specified job
 **
 ** @param [in] Job     Job id
 ** @param [out] None
 ** @return JobStatus:SpiSlave_JobResultType
 */
FUNC(SpiSlave_JobResultType, SPI_SLV_CODE)
SpiSlave_GetJobResult(SpiSlave_JobType Job)
{


    uint8 CoreId = SpiSlave_GetCoreID();
    SpiSlave_JobResultType JobStatus = SPI_SLV_JOB_FAILED;
    struct SpiSlave_Driver_Handler *PerCoreHandler = SpiSlaveHandler[CoreId];

#if (SPI_SLV_DEV_ERROR_DETECT == STD_ON)
    Std_ReturnType ReturnValue;
    ReturnValue = SpiSlave_JobIdDetCheck(Job, SPI_SLV_GETJOBRESULT_SID);

    if (E_OK == ReturnValue)
#endif /* SPI_SLV_DEV_ERROR_DETECT == STD_ON */
    {
        /* Return Job Result */
        JobStatus = PerCoreHandler->JobResult[Job];
    }

#if (SPI_SLV_DEV_ERROR_DETECT == STD_ON)
    else {
        /* No action required */
    }

#endif
    return (JobStatus);
}

/** @brief SpiSlave_GetSequenceResult
**
** getting result of the specified sequence
**
** @param [in] Sequence     Sequence id
** @param [out] None
** @return SeqStatus:SpiSlave_SeqResultType
*/
FUNC(SpiSlave_SeqResultType, SPI_SLV_CODE)
SpiSlave_GetSequenceResult(SpiSlave_SequenceType Sequence)
{
    uint8 CoreId = SpiSlave_GetCoreID();
    SpiSlave_SeqResultType SeqStatus = SPI_SLV_SEQ_FAILED;
    struct SpiSlave_Driver_Handler *PerCoreHandler = SpiSlaveHandler[CoreId];
#if (SPI_SLV_DEV_ERROR_DETECT == STD_ON)
    Std_ReturnType ReturnValue;
    ReturnValue = SpiSlave_SeqIdDetCheck(Sequence, SPI_SLV_GETSEQUENCERESULT_SID);

    if (E_OK == ReturnValue)
#endif /* SPI_SLV_DEV_ERROR_DETECT == STD_ON */
    {
        SeqStatus = PerCoreHandler->SeqResult[Sequence];
    }

#if (SPI_SLV_DEV_ERROR_DETECT == STD_ON)
    else {
        /* No action required */
    }

#endif
    return (SeqStatus);
}

/** @brief SpiSlave_GetVersionInfo
**
** getting result of the specified sequence
**
** @param [out] None
** @param [out] versioninfo     Project version information
** @return None
*/
#if (SPI_SLV_VERSION_INFO_API == STD_ON)
FUNC(void, SPI_SLV_CODE)
SpiSlave_GetVersionInfo(Std_VersionInfoType *versioninfo)
{
#if (SPI_SLV_DEV_ERROR_DETECT == STD_ON)

    /* Check if parameter passed is equal to Null pointer */
    if (versioninfo == NULL_PTR) {
        /* Report to DET  */
        (void)Det_ReportError(SPI_SLV_MODULE_ID, SPI_SLV_INSTANCE_ID, SPI_SLV_GETVERSIONINFO_SID, SPI_SLV_E_PARAM_POINTER);
    } else
#endif /* (SPI_SLV_DEV_ERROR_DETECT == STD_ON) */
    {
        /* Copy the vendor Id */
        versioninfo->vendorID = (uint16)SPI_SLV_VENDOR_ID;
        /* Copy the module Id */
        versioninfo->moduleID = (uint16)SPI_SLV_MODULE_ID;
        /* Copy Software Major Version */
        versioninfo->sw_major_version = SPI_SLV_SW_MAJOR_VERSION;
        /* Copy Software Minor Version */
        versioninfo->sw_minor_version = SPI_SLV_SW_MINOR_VERSION;
        /* Copy Software Patch Version */
        versioninfo->sw_patch_version = SPI_SLV_SW_PATCH_VERSION;
    }
}
#endif

/** @brief SpiSlave_SyncTransmit
**
** Transmitting data synchronously
**
** @param [in] Sequence - Sequence ID
** @param [Out] None
** @return E_OK: Transmission command has been accepted
**         E_NOT_OK: Transmission command has not been accepted
*/
#if ((SPI_SLV_LEVEL_DELIVERED == SPI_SLV_LEVEL_0) || (SPI_SLV_LEVEL_DELIVERED == SPI_SLV_LEVEL_2))

FUNC(Std_ReturnType, SPI_SLV_CODE)
SpiSlave_SyncTransmit(SpiSlave_SequenceType Sequence)
{
    uint8 need_report = FALSE;
    Std_ReturnType ReturnValue = E_OK;
    uint8 CoreId = SpiSlave_GetCoreID();
    struct SpiSlave_Driver_Handler *PerCoreHandler = SpiSlaveHandler[CoreId];
    /* Pointer to get Sequence configuration structure */
    P2CONST(SpiSlave_SequenceCfgType, AUTOMATIC, SPI_SLV_CONFIG_CONST)
    tmpPtrSeqConfig = &SpiSlave_SequenceConfig[Sequence];
#if ((SPI_SLV_LEVEL_DELIVERED == SPI_SLV_LEVEL_2) || \
     (SPI_SLV_SUPPORT_CONCURRENT_SYNC_TRANSMIT == STD_ON))
    struct SpiSlave_Scheduler *Sche = &PerCoreHandler->Scheduler;
#endif
#if (SPI_SLV_DEV_ERROR_DETECT == STD_ON)
    ReturnValue = SpiSlave_SeqIdDetCheck(Sequence, SPI_SLV_SYNCTRANSMIT_SID);
#endif /* End of #if (SPI_SLV_DEV_ERROR_DETECT == STD_ON) */

    /* Check if any DET error has occurred */
    if (E_OK == ReturnValue) {
#if (SPI_SLV_SUPPORT_CONCURRENT_SYNC_TRANSMIT == STD_OFF)
        /*
            SyncTransmit Service to transmit data on the SPI bus .
            When the function SpiSlave_SyncTransmit is called while a sequence is on transmission
            and SPI_SLV_SUPPORT_CONCURRENT_SYNC_TRANSMIT is disabled or another sequence is on
            transmission on same bus, the SPI Handler/Driver shall not take into account this
            new transmission request and the function shall return the value E_NOT_OK (see [SWS_SpiSlave_00114]).
            In this case, the SPI Handler/Driver shall report the SPI_SLV_E_SEQ_IN_PROCESS error according to
            [SWS_BSW_00042] and [SWS_BSW_00045].
        */
        SchM_Enter_SpiSlave_SPI_SLV_EXCLUSIVE_AREA_010();

        if (PerCoreHandler->SpiSyncSeqActiveCnt) {
            ReturnValue = E_NOT_OK;
            need_report = TRUE;
        } else {
            PerCoreHandler->SpiSyncSeqActiveCnt++;
        }

        SchM_Exit_SpiSlave_SPI_SLV_EXCLUSIVE_AREA_010();

#endif
        /*
            This function only build in LEVEL0/LEVEL2. In the case of LEVEL2 or Enable CONCURRENT of Sync ,
            it is necessary to deal with the competition.
        */
#if ((SPI_SLV_LEVEL_DELIVERED == SPI_SLV_LEVEL_2) || \
     (SPI_SLV_SUPPORT_CONCURRENT_SYNC_TRANSMIT == STD_ON))

        /*PRQA S 2991,2995 2*/
        if (E_OK == ReturnValue) {
            /* Check all Bus is idle ?*/
            SchM_Enter_SpiSlave_SPI_SLV_EXCLUSIVE_AREA_010();

            if ((tmpPtrSeqConfig->SeqHwMask & Sche->HwStatusMask) != tmpPtrSeqConfig->SeqHwMask) {
                ReturnValue = E_NOT_OK;
                need_report = TRUE;
            } else {
                /* Lock Bus for Sync Transmit */
                Sche->HwStatusMask &= (~tmpPtrSeqConfig->SeqHwMask);
            }

            SchM_Exit_SpiSlave_SPI_SLV_EXCLUSIVE_AREA_010();
        }

#endif

        if (E_OK == ReturnValue) {
            SchM_Enter_SpiSlave_SPI_SLV_EXCLUSIVE_AREA_010();
            /* Make Driver Status to busy */
            PerCoreHandler->SpiSlave_HandlerStatus = SPI_SLV_BUSY;
#if (SPI_SLV_SUPPORT_CONCURRENT_SYNC_TRANSMIT == STD_ON)
            PerCoreHandler->SpiSyncSeqActiveCnt++;
#endif
            SchM_Exit_SpiSlave_SPI_SLV_EXCLUSIVE_AREA_010();
            /* Initiate the Sequence Transmission */
            ReturnValue = SpiSlave_SeqSyncTransmit(Sequence, tmpPtrSeqConfig);
            SchM_Enter_SpiSlave_SPI_SLV_EXCLUSIVE_AREA_010();
#if ((SPI_SLV_LEVEL_DELIVERED == SPI_SLV_LEVEL_2) || \
     (SPI_SLV_SUPPORT_CONCURRENT_SYNC_TRANSMIT == STD_ON))
            Sche->HwStatusMask |= tmpPtrSeqConfig->SeqHwMask;
#endif
            PerCoreHandler->SpiSyncSeqActiveCnt--;

            if (0u == PerCoreHandler->SpiSyncSeqActiveCnt){
                PerCoreHandler->SpiSlave_HandlerStatus = SPI_SLV_IDLE;
            }
            SchM_Exit_SpiSlave_SPI_SLV_EXCLUSIVE_AREA_010();
        } else {
            /* Do nothing */
        }
    } else {
        /* Do nothing */
    }

    if (TRUE == need_report){
#if (SPI_SLV_DEV_ERROR_DETECT == STD_ON)
        (void)Det_ReportRuntimeError(SPI_SLV_MODULE_ID, SPI_SLV_INSTANCE_ID, SPI_SLV_SYNCTRANSMIT_SID,
                               SPI_SLV_E_SEQ_IN_PROCESS);
#endif
    }
    return (ReturnValue);
}

#endif

/** @brief SpiSlave_GetHWUnitStatus
**
** status of the SPI Hardware micro-controller peripheral
**
** @param [in] HWUnit - ID of SPI HW
** @param [out] None
** @return SpiSlave_StatusType
*/
#if (SPI_SLV_HW_STATUS_API == STD_ON)

FUNC(SpiSlave_StatusType, SPI_SLV_CODE)
SpiSlave_GetHWUnitStatus(SpiSlave_HWUnitType HWUnit)
{
    SpiSlave_StatusType HWStatus = SPI_SLV_UNINIT;

#if (SPI_SLV_DEV_ERROR_DETECT == STD_ON)
    struct SpiSlave_Driver_Handler *PerCoreHandler = SpiSlaveHandler[SpiSlave_GetCoreID()];

    /* Check if SPI Driver is initialized */
    if (PerCoreHandler->SpiSlave_HandlerStatus == SPI_SLV_UNINIT)
    {
        /* Report to DET */
        (void)Det_ReportError(SPI_SLV_MODULE_ID, SPI_SLV_INSTANCE_ID, SPI_SLV_GETHWUNITSTATUS_SID, SPI_SLV_E_UNINIT);
    }
    else if (HWUnit >= SPI_SLV_TOTAL_HW_COUNT)
    {
        /* Report to DET */
        (void)Det_ReportError(SPI_SLV_MODULE_ID, SPI_SLV_INSTANCE_ID, SPI_SLV_GETHWUNITSTATUS_SID, SPI_SLV_E_PARAM_UNIT);
    }
    else
#endif /* SPI_SLV_DEV_ERROR_DETECT == STD_ON */
    {
        /* Check if the Hardware is in Busy State */
        HWStatus = SpiSlave_GetHWStatus(HWUnit);
    }
    return HWStatus;
}

#endif /* End of (SPI_SLV_HW_STATUS_API == STD_ON) */

/** @brief SpiSlave_Cancel
**
** Cancel the transmission of a on-going sequence
**
** @param [in] Sequence - Sequence ID
** @param [out] None
** @return None
*/
#if (SPI_SLV_CANCEL_API == STD_ON)

FUNC(void, SPI_SLV_CODE)
SpiSlave_Cancel(SpiSlave_SequenceType Sequence)
{
#if (SPI_SLV_DEV_ERROR_DETECT == STD_ON)
    uint8 CoreId = SpiSlave_GetCoreID();
    struct SpiSlave_Driver_Handler *PerCoreHandler = SpiSlaveHandler[CoreId];
    /* To return DET Error Status */
    Std_ReturnType ReturnValue;
    /* Check if Sequence ID is valid */
    ReturnValue = SpiSlave_SeqIdDetCheck(Sequence, SPI_SLV_CANCEL_SID);

    if (E_OK == ReturnValue) {
        /* If Sequence is in Pending State */
        if (PerCoreHandler->SeqResult[Sequence] != SPI_SLV_SEQ_PENDING) {
            (void)Det_ReportError(SPI_SLV_MODULE_ID, SPI_SLV_INSTANCE_ID, SPI_SLV_CANCEL_SID, SPI_SLV_E_CANCEL_ERROR);
            ReturnValue = E_NOT_OK;
        } else {
            /* No action required */
        }
    }

    if (E_OK == ReturnValue)
#endif
    {
        SchM_Enter_SpiSlave_SPI_SLV_EXCLUSIVE_AREA_012();
        SpiSlave_SeqCancel(Sequence);
        SchM_Exit_SpiSlave_SPI_SLV_EXCLUSIVE_AREA_012();
    }
}
#endif /* End of (SPI_SLV_CANCEL_API == STD_ON ) */
/** @brief SpiSlave_SetAsyncMode
**
** setting the asynchronous mode
**
** @param [in] Mode - New Mode Required
** @param [out] None
** @return  E_OK: Setting command has been done
**          E_NOT_OK: setting command has not been accepted
*/
#if (SPI_SLV_LEVEL_DELIVERED == SPI_SLV_LEVEL_2)

FUNC(Std_ReturnType, SPI_SLV_CODE)
SpiSlave_SetAsyncMode(SpiSlave_AsyncModeType Mode)
{
    uint8 CoreId = SpiSlave_GetCoreID();
    struct SpiSlave_Driver_Handler *PerCoreHandler = SpiSlaveHandler[CoreId];
    Std_ReturnType ReturnValue = E_OK;
#if (SPI_SLV_DEV_ERROR_DETECT == STD_ON)

    /* Check if SPI Driver is initialized */
    if (SPI_SLV_UNINIT == PerCoreHandler->SpiSlave_HandlerStatus) {
        /* Report to DET */
        (void)Det_ReportError(SPI_SLV_MODULE_ID, SPI_SLV_INSTANCE_ID, SPI_SLV_SETAYNCMODE_SID, SPI_SLV_E_UNINIT);
        ReturnValue = E_NOT_OK;
    } else
#endif /* End of (SPI_SLV_DEV_ERROR_DETECT == STD_ON) */
    {
        /*Check if the Async handler is busy*/
        SchM_Enter_SpiSlave_SPI_SLV_EXCLUSIVE_AREA_013();

        if (PerCoreHandler->SpiSlave_HandlerAsyncStatus == SPI_SLV_BUSY) {
            ReturnValue = E_NOT_OK;
        } else {
            /* No action required */
        }

        if (ReturnValue == E_OK) {
            if (((Mode == SPI_SLV_POLLING_MODE) || (Mode == SPI_SLV_INTERRUPT_MODE))) {
                /* Update the mode of operation */
                SpiSlave_AsyncModeSet(Mode);
            } else {
                ReturnValue = E_NOT_OK;
            }
        }

        SchM_Exit_SpiSlave_SPI_SLV_EXCLUSIVE_AREA_013();
    }

    return (ReturnValue);
}

#endif /* End of (SPI_SLV_LEVEL_DELIVERED == SPI_SLV_LEVEL_2) */
#define SPI_SLV_STOP_SEC_CODE
#include "SpiSlave_MemMap.h"

#define SPI_SLV_START_SEC_CODE_FAST
#include "SpiSlave_MemMap.h"
/** @brief SpiSlave_MainFunction_Handling
**
** asynchronous transmission in polling mode
**
** @param [in] None
** @param [out] None
** @return None
*/
#if (SPI_SLV_LEVEL_DELIVERED == SPI_SLV_LEVEL_2)
FUNC(void, SPI_SLV_CODE)
SpiSlave_MainFunction_Handling(void)
{
    uint8 CoreId = SpiSlave_GetCoreID();
    struct SpiSlave_Driver_Handler *PerCoreHandler = SpiSlaveHandler[CoreId];
    struct SpiSlave_Scheduler *Sche = &PerCoreHandler->Scheduler;

    /* Check if SPI Driver is initialized */
    if (SPI_SLV_UNINIT == PerCoreHandler->SpiSlave_HandlerStatus) {
#if (SPI_SLV_DEV_ERROR_DETECT == STD_ON)
        /* Report to DET */
        (void)Det_ReportError(SPI_SLV_MODULE_ID, SPI_SLV_INSTANCE_ID, SPI_SLV_MAINFUNCTION_HANDLING_SID, SPI_SLV_E_UNINIT);
#endif /* SPI_SLV_DEV_ERROR_DETECT == STD_ON */
    }
    else
    {
        /* Check if function is invoked in Polling mode */
        if (Sche->SchedulerMode == SPI_SLV_POLLING_MODE) {
            for (uint8 HwId = 0; HwId < SPI_SLV_TOTAL_HW_COUNT; HwId++) {
                if (SpiSlave_InstanceMask_Config[CoreId] & (0x01u << HwId)) {
                    SchM_Enter_SpiSlave_SPI_SLV_EXCLUSIVE_AREA_015();
                    SpiSlave_HwMainFunctionHandling(HwId);
                    SchM_Exit_SpiSlave_SPI_SLV_EXCLUSIVE_AREA_015();
                }
            }
        }
    }
}
#endif
/** **************************************************************************************
 * \brief This function call after spislave finished one sequence transmit.
 *
 * \verbatim
 * Syntax             : Std_ReturnType SpiSlave_GetTransmittedBytes(
 *                           SpiSlave_SequenceType SequenceId)
 *
 * Service ID[hex]    : 0x00
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : reentrant
 *
 * Parameters (in)    : SequenceId tag sequence id.
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : Get the SpiSlave Specific Sequence transmission data length.
 * \endverbatim
 * Traceability       :
 *****************************************************************************************/
FUNC(sint32, SPI_SLV_CODE)SpiSlave_GetTransmittedBytes(SpiSlave_SequenceType SequenceId)
{
    sint32 len;
    uint8 CoreId = SpiSlave_GetCoreID();

    struct SpiSlave_Driver_Handler *PerCoreHandler = SpiSlaveHandler[CoreId];
    struct SpiSlave_SeqNode *SeqNode = PerCoreHandler->SeqNode;

    if (NULL_PTR != SeqNode[SequenceId].JobQueue.Next) {
        /*PRQA S 2810 2*/
        struct SpiSlave_JobNode *JobItem = SpiSlaveGetJobNode(SeqNode[SequenceId].JobQueue.Next);
        struct mld_spi_slv_module *bus = &PerCoreHandler->SpiBus[SpiSlave_JobConfig[JobItem->JobId].HWUnit].Bus;

        len = mld_spi_slv_get_length(bus);
        return len;
    } else {
        return -1;
    }
}

#define SPI_SLV_STOP_SEC_CODE_FAST
#include "SpiSlave_MemMap.h"

#ifdef __cplusplus
}
#endif

/*******************************************************************************
**                          End of File                                       **
*******************************************************************************/
